/*
 * Copyright 2009 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

package com.google.gwt.xhr.client;

import com.google.gwt.core.client.JavaScriptObject;

/**
 * The native XMLHttpRequest2 object. Most applications should use the higher- level
 * {@link com.google.gwt.http.client.RequestBuilder} class unless they need specific functionality
 * provided by the XMLHttpRequest object.
 * 
 * See <a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/"
 * >http://dev.w3.org/2006/webapi/XMLHttpRequest-2/</a>/
 */

public class XMLHTTPRequest2 extends XMLHttpRequest {
  
  /**
   * Constructor
   */
  protected XMLHTTPRequest2() {

  }

  /**
   * Creates an AnonXMLHttpRequest object.
   * 
   * @return the created object
   */
  public static native XMLHttpRequest createAnon() /*-{
    // Don't check window.XMLHttpRequest, because it can
    // cause cross-site problems on IE8 if window's URL
    // is javascript:'' .
    if ($wnd.AnonXMLHttpRequest) {
      return new $wnd.AnonXMLHttpRequest();
    } else {
      //return the normal XMLHttpRequest
      return create();
    }
  }-*/;

  /**
   * Get's the request's response.
   * <p>
   * See <a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#dom-xmlhttprequest-response"
   * >http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#dom-xmlhttprequest-response</a>.
   * 
   * @return the responseType
   */
  public final native <T> T getResponse() /*-{
    return this.response;
  }-*/;  
  
  /**
   * Get's the request's responseType attribute.
   * <p>
   * See <a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#dom-xmlhttprequest-responsetype"
   * >http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#dom-xmlhttprequest-responsetype</a>.
   * 
   * @return the responseType
   */
  public final native String getResponseType() /*-{
    return this.responseType;
  }-*/;
  
  /**
   * Get's the request's timeout attribute.
   * <p>
   * See <a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#dom-xmlhttprequest-timeout"
   * >http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#dom-xmlhttprequest-timeout</a>.
   * 
   * @return the timeout value
   */
  public final native int getTimeOut() /*-{
    return this.timeout;
  }-*/;
  
  /**
   * Get's the request's upload attribute.
   * <p>
   * See <a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#dom-xmlhttprequest-upload"
   * >http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#dom-xmlhttprequest-upload</a>.
   * 
   * @return the upload value
   */
  public final native XmlHttpRequestUpload getUpload() /*-{
    return this.upload;
  }-*/;

  /**
   * Get's the request's withCredentials attribute.
   * <p>
   * See <a
   * href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#dom-xmlhttprequest-withcredentials"
   * >http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#dom-xmlhttprequest-withcredentials</a>.
   * 
   * @return the withCredentials value
   */
  public final native boolean getWithCredentials() /*-{
    return this.withCredentials;
  }-*/;

  
  /**
   * call the overrideMimeType function.
   * <p>
   * See <a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#dom-xmlhttprequest-overridemimetype"
   * >http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#dom-xmlhttprequest-overridemimetype</a>.
   * 
   * @param mimeType the new mimeType
   */
  public final native void overrideMimeType(String mimeType) /*-{
    this.overrideMimeType(mimeType);
  }-*/;

  /**
   * Initiates a request with data.  If there is no data, specify null.
   * <p>
   * See <a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#dom-xmlhttprequest-send"
   * >http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#dom-xmlhttprequest-send</a>.
   * 
   * @param requestData the data to be sent with the request
   */
  public final native <T> void send(T requestData) /*-{
    this.send(requestData);
  }-*/;

  /**
   * Sets the {@link ProgressChangeHandler} to be notified when the request start.
   * <p>
   * See <a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#event-xhr-loadstart"
   * >http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#event-xhr-loadstart</a>.
   * 
   */
  public final native void setOnLoadStart(ProgressChangeHandler handler) /*-{
    // The 'this' context is always supposed to point to the xhr object in the
    // onreadystatechange handler, but we reference it via closure to be extra sure.
    var _this = this;
    this.onloadstart = $entry(function() {
    handler.@com.google.gwt.xhr.client.ProgressChangeHandler::onLoadStart(Lcom/google/gwt/xhr/client/XMLHttpRequest;)(_this);
    });
  }-*/;

  /**
   * Sets the {@link ProgressChangeHandler} to be notified when sending and loading data.
   * <p>
   * See <a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#event-xhr-progress
   * >http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#event-xhr-progress</a>.
   * 
   */
  public final native void setOnProgress(ProgressChangeHandler handler) /*-{
    // The 'this' context is always supposed to point to the xhr object in the
    // onreadystatechange handler, but we reference it via closure to be extra sure.
    var _this = this;
    this.onprogress = $entry(function() {
    handler.@com.google.gwt.xhr.client.ProgressChangeHandler::onProgress(Lcom/google/gwt/xhr/client/XMLHttpRequest;)(_this);
    });
  }-*/;

  /**
   * Sets the {@link ProgressChangeHandler} to be notified when the request has been aborted.
   * <p>
   * See <a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#event-xhr-abort"
   * >http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#event-xhr-abort</a>.
   * 
   */
  public final native void setOnAbort(ProgressChangeHandler handler) /*-{
    // The 'this' context is always supposed to point to the xhr object in the
    // onreadystatechange handler, but we reference it via closure to be extra sure.
    var _this = this;
    this.onabort = $entry(function() {
    handler.@com.google.gwt.xhr.client.ProgressChangeHandler::onAbort(Lcom/google/gwt/xhr/client/XMLHttpRequest;)(_this);
    });
  }-*/;

  /**
   * Sets the {@link ProgressChangeHandler} to be notified when the request has failed.
   * <p>
   * See <a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#event-xhr-error"
   * >http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#event-xhr-error</a>.
   * 
   */
  public final native void setOnError(ProgressChangeHandler handler) /*-{
    // The 'this' context is always supposed to point to the xhr object in the
    // onreadystatechange handler, but we reference it via closure to be extra sure.
    var _this = this;
    this.onerror = $entry(function() {
    handler.@com.google.gwt.xhr.client.ProgressChangeHandler::onError(Lcom/google/gwt/xhr/client/XMLHttpRequest;)(_this);
    });
  }-*/;

  /**
   * Sets the {@link ProgressChangeHandler} to be notified when the request has successfully
   * completed.
   * <p>
   * See <a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#event-xhr-load"
   * >http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#event-xhr-load</a>.
   * 
   */
  public final native void setOnLoad(ProgressChangeHandler handler) /*-{
    // The 'this' context is always supposed to point to the xhr object in the
    // onreadystatechange handler, but we reference it via closure to be extra sure.
    var _this = this;
    this.onload = $entry(function() {
    handler.@com.google.gwt.xhr.client.ProgressChangeHandler::onLoad(Lcom/google/gwt/xhr/client/XMLHttpRequest;)(_this);
    });
  }-*/;

  /**
   * Sets the {@link ProgressChangeHandler} to be notified when the author specified timeout has
   * passed before the request could complete.
   * <p>
   * See <a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#event-xhr-timeout"
   * >http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#event-xhr-timeout</a>.
   * 
   */
  public final native void setOnTimeOut(ProgressChangeHandler handler) /*-{
    // The 'this' context is always supposed to point to the xhr object in the
    // onreadystatechange handler, but we reference it via closure to be extra sure.
    var _this = this;
    this.ontimeout = $entry(function() {
    handler.@com.google.gwt.xhr.client.ProgressChangeHandler::onTimeOut(Lcom/google/gwt/xhr/client/XMLHttpRequest;)(_this);
    });
  }-*/;

  /**
   * Sets the {@link ProgressChangeHandler} to be notified when the request has completed (either in
   * success or failure).
   * <p>
   * See <a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#event-xhr-loadend"
   * >http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#event-xhr-loadend</a>.
   * 
   */
  public final native void setOnLoadEnd(ProgressChangeHandler handler) /*-{
    // The 'this' context is always supposed to point to the xhr object in the
    // onreadystatechange handler, but we reference it via closure to be extra sure.
    var _this = this;
    this.onloadend = $entry(function() {
    handler.@com.google.gwt.xhr.client.ProgressChangeHandler::onLoadEnd(Lcom/google/gwt/xhr/client/XMLHttpRequest;)(_this);
    });
  }-*/;

  /**
   * Sets the responseType attribute.
   * <p>
   * See <a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#dom-xmlhttprequest-responsetype"
   * >http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#dom-xmlhttprequest-responsetype</a>.
   * 
   * @param responseType the XHR's responseType value
   */
  public final native void setResponseType (String responseType) /*-{
    this.responseType=responseType;
  }-*/;
  
  /**
   * Sets the timeout attribute.
   * <p>
   * See <a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#dom-xmlhttprequest-timeout"
   * >http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#dom-xmlhttprequest-timeout</a>.
   * 
   * @param timeout the XHR's timeout value
   */
  public final native void setTimeOut(int timeout) /*-{
    this.timeout=timeout;
  }-*/;

  /**
   * Sets the upload attribute.
   * <p>
   * See <a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#the-upload-attribute"
   * >http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#the-upload-attribute</a>.
   * 
   * @param upload the XHR's upload value
   */
  public final native void setUpload(JavaScriptObject upload) /*-{
    this.upload=upload;
  }-*/;

  /**
   * Sets the withCredentials attribute.
   * <p>
   * See <a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#dom-xmlhttprequest-withcredentials"
   * >http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#dom-xmlhttprequest-withcredentials</a>.
   * 
   * @param timeout the XHR's withCredentials value
   */
  public final native void setWithCredentials(boolean withCredentials) /*-{
    this.withCredentials=withCredentials;
  }-*/;

}
